1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.collect.testing.google;
18
19 import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_VALUES;
20 import static com.google.common.collect.testing.features.CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION;
21 import static com.google.common.collect.testing.features.CollectionFeature.RESTRICTS_ELEMENTS;
22 import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_ADD;
23 import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_REMOVE;
24 import static com.google.common.collect.testing.features.CollectionSize.SEVERAL;
25 import static com.google.common.collect.testing.features.CollectionSize.ZERO;
26
27 import com.google.common.annotations.GwtCompatible;
28 import com.google.common.annotations.GwtIncompatible;
29 import com.google.common.collect.Multiset;
30 import com.google.common.collect.Multiset.Entry;
31 import com.google.common.collect.testing.Helpers;
32 import com.google.common.collect.testing.features.CollectionFeature;
33 import com.google.common.collect.testing.features.CollectionSize;
34
35 import java.lang.reflect.Method;
36 import java.util.Arrays;
37 import java.util.ConcurrentModificationException;
38 import java.util.Iterator;
39 import java.util.List;
40
41
42
43
44
45
46
47
48
49
50 @GwtCompatible(emulated = true)
51 public abstract class AbstractMultisetSetCountTester<E>
52 extends AbstractMultisetTester<E> {
53
54
55
56
57
58
59
60
61 private void assertSetCount(E element, int count) {
62 setCountCheckReturnValue(element, count);
63
64 assertEquals(
65 "multiset.count() should return the value passed to setCount()",
66 count, getMultiset().count(element));
67
68 int size = 0;
69 for (Multiset.Entry<E> entry : getMultiset().entrySet()) {
70 size += entry.getCount();
71 }
72 assertEquals(
73 "multiset.size() should be the sum of the counts of all entries",
74 size, getMultiset().size());
75 }
76
77
78
79
80 abstract void setCountCheckReturnValue(E element, int count);
81
82
83
84
85
86
87
88
89
90
91
92 abstract void setCountNoCheckReturnValue(E element, int count);
93
94 private void assertSetCountIncreasingFailure(E element, int count) {
95 try {
96 setCountNoCheckReturnValue(element, count);
97 fail("a call to multiset.setCount() to increase an element's count "
98 + "should throw");
99 } catch (UnsupportedOperationException expected) {
100 }
101 }
102
103 private void assertSetCountDecreasingFailure(E element, int count) {
104 try {
105 setCountNoCheckReturnValue(element, count);
106 fail("a call to multiset.setCount() to decrease an element's count "
107 + "should throw");
108 } catch (UnsupportedOperationException expected) {
109 }
110 }
111
112
113
114 private void assertZeroToZero() {
115 assertSetCount(samples.e3, 0);
116 }
117
118 private void assertOneToOne() {
119 assertSetCount(samples.e0, 1);
120 }
121
122 private void assertThreeToThree() {
123 initThreeCopies();
124 assertSetCount(samples.e0, 3);
125 }
126
127 @CollectionFeature.Require(SUPPORTS_ADD)
128 public void testSetCount_zeroToZero_addSupported() {
129 assertZeroToZero();
130 }
131
132 @CollectionFeature.Require(SUPPORTS_REMOVE)
133 public void testSetCount_zeroToZero_removeSupported() {
134 assertZeroToZero();
135 }
136
137 @CollectionFeature.Require(absent = {SUPPORTS_ADD, SUPPORTS_REMOVE})
138 public void testSetCount_zeroToZero_unsupported() {
139 try {
140 assertZeroToZero();
141 } catch (UnsupportedOperationException tolerated) {
142 }
143 }
144
145 @CollectionSize.Require(absent = ZERO)
146 @CollectionFeature.Require(SUPPORTS_ADD)
147 public void testSetCount_oneToOne_addSupported() {
148 assertOneToOne();
149 }
150
151 @CollectionSize.Require(absent = ZERO)
152 @CollectionFeature.Require(SUPPORTS_REMOVE)
153 public void testSetCount_oneToOne_removeSupported() {
154 assertOneToOne();
155 }
156
157 @CollectionSize.Require(absent = ZERO)
158 @CollectionFeature.Require(absent = {SUPPORTS_ADD, SUPPORTS_REMOVE})
159 public void testSetCount_oneToOne_unsupported() {
160 try {
161 assertOneToOne();
162 } catch (UnsupportedOperationException tolerated) {
163 }
164 }
165
166 @CollectionSize.Require(SEVERAL)
167 @CollectionFeature.Require(SUPPORTS_ADD)
168 public void testSetCount_threeToThree_addSupported() {
169 assertThreeToThree();
170 }
171
172 @CollectionSize.Require(SEVERAL)
173 @CollectionFeature.Require(SUPPORTS_REMOVE)
174 public void testSetCount_threeToThree_removeSupported() {
175 assertThreeToThree();
176 }
177
178 @CollectionSize.Require(SEVERAL)
179 @CollectionFeature.Require(absent = {SUPPORTS_ADD, SUPPORTS_REMOVE})
180 public void testSetCount_threeToThree_unsupported() {
181 try {
182 assertThreeToThree();
183 } catch (UnsupportedOperationException tolerated) {
184 }
185 }
186
187
188
189 @CollectionFeature.Require(SUPPORTS_ADD)
190 public void testSetCount_zeroToOne_supported() {
191 assertSetCount(samples.e3, 1);
192 }
193
194 @CollectionFeature.Require({SUPPORTS_ADD,
195 FAILS_FAST_ON_CONCURRENT_MODIFICATION})
196 public void testSetCountZeroToOneConcurrentWithIteration() {
197 try {
198 Iterator<E> iterator = collection.iterator();
199 assertSetCount(samples.e3, 1);
200 iterator.next();
201 fail("Expected ConcurrentModificationException");
202 } catch (ConcurrentModificationException expected) {
203
204 }
205 }
206
207 @CollectionFeature.Require({SUPPORTS_ADD,
208 FAILS_FAST_ON_CONCURRENT_MODIFICATION})
209 public void testSetCountZeroToOneConcurrentWithEntrySetIteration() {
210 try {
211 Iterator<Entry<E>> iterator = getMultiset().entrySet().iterator();
212 assertSetCount(samples.e3, 1);
213 iterator.next();
214 fail("Expected ConcurrentModificationException");
215 } catch (ConcurrentModificationException expected) {
216
217 }
218 }
219
220 @CollectionFeature.Require(SUPPORTS_ADD)
221 public void testSetCount_zeroToThree_supported() {
222 assertSetCount(samples.e3, 3);
223 }
224
225 @CollectionSize.Require(absent = ZERO)
226 @CollectionFeature.Require(SUPPORTS_ADD)
227 public void testSetCount_oneToThree_supported() {
228 assertSetCount(samples.e0, 3);
229 }
230
231 @CollectionFeature.Require(absent = SUPPORTS_ADD)
232 public void testSetCount_zeroToOne_unsupported() {
233 assertSetCountIncreasingFailure(samples.e3, 1);
234 }
235
236 @CollectionFeature.Require(absent = SUPPORTS_ADD)
237 public void testSetCount_zeroToThree_unsupported() {
238 assertSetCountIncreasingFailure(samples.e3, 3);
239 }
240
241 @CollectionSize.Require(absent = ZERO)
242 @CollectionFeature.Require(absent = SUPPORTS_ADD)
243 public void testSetCount_oneToThree_unsupported() {
244 assertSetCountIncreasingFailure(samples.e3, 3);
245 }
246
247
248
249 @CollectionSize.Require(absent = ZERO)
250 @CollectionFeature.Require(SUPPORTS_REMOVE)
251 public void testSetCount_oneToZero_supported() {
252 assertSetCount(samples.e0, 0);
253 }
254
255 @CollectionFeature.Require({SUPPORTS_REMOVE,
256 FAILS_FAST_ON_CONCURRENT_MODIFICATION})
257 @CollectionSize.Require(absent = ZERO)
258 public void testSetCountOneToZeroConcurrentWithIteration() {
259 try {
260 Iterator<E> iterator = collection.iterator();
261 assertSetCount(samples.e0, 0);
262 iterator.next();
263 fail("Expected ConcurrentModificationException");
264 } catch (ConcurrentModificationException expected) {
265
266 }
267 }
268
269 @CollectionFeature.Require({SUPPORTS_REMOVE,
270 FAILS_FAST_ON_CONCURRENT_MODIFICATION})
271 @CollectionSize.Require(absent = ZERO)
272 public void testSetCountOneToZeroConcurrentWithEntrySetIteration() {
273 try {
274 Iterator<Entry<E>> iterator = getMultiset().entrySet().iterator();
275 assertSetCount(samples.e0, 0);
276 iterator.next();
277 fail("Expected ConcurrentModificationException");
278 } catch (ConcurrentModificationException expected) {
279
280 }
281 }
282
283 @CollectionSize.Require(SEVERAL)
284 @CollectionFeature.Require(SUPPORTS_REMOVE)
285 public void testSetCount_threeToZero_supported() {
286 initThreeCopies();
287 assertSetCount(samples.e0, 0);
288 }
289
290 @CollectionSize.Require(SEVERAL)
291 @CollectionFeature.Require(SUPPORTS_REMOVE)
292 public void testSetCount_threeToOne_supported() {
293 initThreeCopies();
294 assertSetCount(samples.e0, 1);
295 }
296
297 @CollectionSize.Require(absent = ZERO)
298 @CollectionFeature.Require(absent = SUPPORTS_REMOVE)
299 public void testSetCount_oneToZero_unsupported() {
300 assertSetCountDecreasingFailure(samples.e0, 0);
301 }
302
303 @CollectionSize.Require(SEVERAL)
304 @CollectionFeature.Require(absent = SUPPORTS_REMOVE)
305 public void testSetCount_threeToZero_unsupported() {
306 initThreeCopies();
307 assertSetCountDecreasingFailure(samples.e0, 0);
308 }
309
310 @CollectionSize.Require(SEVERAL)
311 @CollectionFeature.Require(absent = SUPPORTS_REMOVE)
312 public void testSetCount_threeToOne_unsupported() {
313 initThreeCopies();
314 assertSetCountDecreasingFailure(samples.e0, 1);
315 }
316
317
318
319 @CollectionSize.Require(absent = ZERO)
320 @CollectionFeature.Require({SUPPORTS_REMOVE, ALLOWS_NULL_VALUES})
321 public void testSetCount_removeNull_nullSupported() {
322 initCollectionWithNullElement();
323 assertSetCount(null, 0);
324 }
325
326 @CollectionFeature.Require(value = {SUPPORTS_ADD, ALLOWS_NULL_VALUES},
327 absent = RESTRICTS_ELEMENTS)
328 public void testSetCount_addNull_nullSupported() {
329 assertSetCount(null, 1);
330 }
331
332 @CollectionFeature.Require(value = SUPPORTS_ADD, absent = ALLOWS_NULL_VALUES)
333 public void testSetCount_addNull_nullUnsupported() {
334 try {
335 setCountNoCheckReturnValue(null, 1);
336 fail("adding null with setCount() should throw NullPointerException");
337 } catch (NullPointerException expected) {
338 }
339 }
340
341 @CollectionFeature.Require(ALLOWS_NULL_VALUES)
342 public void testSetCount_noOpNull_nullSupported() {
343 try {
344 assertSetCount(null, 0);
345 } catch (UnsupportedOperationException tolerated) {
346 }
347 }
348
349 @CollectionFeature.Require(absent = ALLOWS_NULL_VALUES)
350 public void testSetCount_noOpNull_nullUnsupported() {
351 try {
352 assertSetCount(null, 0);
353 } catch (NullPointerException tolerated) {
354 } catch (UnsupportedOperationException tolerated) {
355 }
356 }
357
358 @CollectionSize.Require(absent = ZERO)
359 @CollectionFeature.Require(ALLOWS_NULL_VALUES)
360 public void testSetCount_existingNoNopNull_nullSupported() {
361 initCollectionWithNullElement();
362 try {
363 assertSetCount(null, 1);
364 } catch (UnsupportedOperationException tolerated) {
365 }
366 }
367
368
369
370 @CollectionFeature.Require(SUPPORTS_REMOVE)
371 public void testSetCount_negative_removeSupported() {
372 try {
373 setCountNoCheckReturnValue(samples.e3, -1);
374 fail("calling setCount() with a negative count should throw "
375 + "IllegalArgumentException");
376 } catch (IllegalArgumentException expected) {
377 }
378 }
379
380 @CollectionFeature.Require(absent = SUPPORTS_REMOVE)
381 public void testSetCount_negative_removeUnsupported() {
382 try {
383 setCountNoCheckReturnValue(samples.e3, -1);
384 fail("calling setCount() with a negative count should throw "
385 + "IllegalArgumentException or UnsupportedOperationException");
386 } catch (IllegalArgumentException expected) {
387 } catch (UnsupportedOperationException expected) {
388 }
389 }
390
391
392
393
394
395
396
397
398 @GwtIncompatible("reflection")
399 public static List<Method> getSetCountDuplicateInitializingMethods() {
400 return Arrays.asList(
401 getMethod("testSetCount_threeToThree_removeSupported"),
402 getMethod("testSetCount_threeToZero_supported"),
403 getMethod("testSetCount_threeToOne_supported"));
404 }
405
406 @GwtIncompatible("reflection")
407 private static Method getMethod(String methodName) {
408 return Helpers.getMethod(AbstractMultisetSetCountTester.class, methodName);
409 }
410 }